package ngat.oss;

import ngat.message.OSS.*;
import ngat.util.logging.*;
import ngat.phase2.*; 
import ngat.instrument.*;
import ngat.phase2.nonpersist.*;

import java.util.*;
import java.io.*;

import jyd.dbms.*;
import jyd.storable.*;
import jyd.collection.*;

/**
 * Action: Sent by USR to add a a CoI user to a Proposal.
 * @author S.N.Fraser
 */
public class ADD_COI_USERImpl extends TransactionImpl {
    
    /** The path used to locate the Proposal in the OSS database. */
    protected Path proposalPath;
    
    /** The Path for the user who is being added as CoI.*/
    protected String userId;
       
    /** Create an ADD_COI_USERImpl for the specified request.*/
    public ADD_COI_USERImpl(ADD_COI_USER request) {
	super(request);
	this.proposalPath = request.getProposalPath();
	this.userId       = request.getUserId();
    }
    
    /**
     * Add a co-investigator.
     */
    public TRANSACTION_DONE exec() { 

	Transaction t = null;
	try {
	    t = Transaction.current();
	    
	    Root root = OSS_Utilities.fetchRoot(proposalPath);
	    Tag  tag          = null;  
	    User user         = null;
	    User searchUser   = null;
	    Proposal proposal = null;
	    
	    // Find the user within its Tag.
	    Iterator it1 = root.listAllTags();
	    while (it1.hasNext()) {
		tag = (Tag)it1.next();
		Iterator it2 = tag.listAllUsers();
		while (it2.hasNext()) {
		    user = (User)it2.next();
		    if (user.getName().equals(userId)) {
			searchUser = user;
		    }
		}
	    }
	    
	    // Not there.
	    if (searchUser == null) {
		logger.log(1, CLASS, id, "exec", 
			   "User: "+userId+" Not in database:");
		
		return error(TRANSACTION.PATH_RESOLUTION_ERROR,
			     "Could not find User: "+userId);
	    }			
	    
	    // Ok found.
	    logger.log(1, "ADD_COI_USERImpl", id, "exec", "Found user: "+userId+" ("+
		       searchUser.getFname()+" "+searchUser.getSname()+
		       " email: "+ searchUser.getEmail());
	    
	    // Locate the Proposal.	   
	    try {
		proposal = OSS_Utilities.fetchProposal(proposalPath);
	    } catch (IOException iox) {
		logger.log(1, CLASS, id, "exec",
			   "Proposal: "+proposalPath.toString()+
			   " Error fetching from Database: "+iox);
		
		return error(TRANSACTION.DATABASE_READ_ERROR,			   
			     "Proposal: "+proposalPath.toString()+
			     " Error reading from database: "+iox);
	    }		
	    
	    
	    
	    // Not there.
	    if (proposal == null) {
		logger.log(1, "ADD_COI_USERImpl", id, "exec", 
			   "Proposal: "+proposalPath.toString()+" Not in database");
		
		return error(TRANSACTION.PATH_RESOLUTION_ERROR, 
			     "Could not find Proposal: "+proposalPath.toString());
	    } 
	    
	    // See if the User already has the Proposal return silently.
	    if (searchUser.findCoIProposal(proposal.getName()) != null) {
		logger.log(1, "ADD_COI_USERImpl", id, "exec", "User: "+userId+
			   " already CoI for Proposal: "+proposalPath);
		
		ADD_COI_USER_DONE done = new ADD_COI_USER_DONE(id);
		done.setAdded(false);
		done.setSuccessful(true);
		return done;
	    }
	    
	    // Add it in.
	    searchUser.addCoIProposal(proposal.getName());
	    logger.log(1, "ADD_COI_USERImpl", id, "exec", "Added User: "+userId);
	    
	    // Make sure it inserted.
	    if (searchUser.findCoIProposal(proposal.getName()) == null) {
		logger.log(1, "ADD_COI_USERImpl", id, "exec", 
			   "User: "+userId+
			   " was not added as CoI for Proposal: "+proposalPath);
		return error(TRANSACTION.DATABASE_UPDATE_ERROR,
			     "User could not be added as CoI");
	    }
	   
	    ADD_COI_USER_DONE done = new ADD_COI_USER_DONE(id);
	    done.setAdded(true);
	    done.setSuccessful(true);
	    return done;
	    
	} finally {
	    t.commit();
	}
    }
    
}

